package cloud.daodao.storm.security.service;

import cloud.daodao.storm.security.config.AppConfig;
import cloud.daodao.storm.security.constant.CacheConstant;
import cloud.daodao.storm.common.security.error.SecurityError;
import cloud.daodao.storm.common.security.model.captcha.CaptchaData;
import cloud.daodao.storm.common.security.model.captcha.CaptchaParam;
import cloud.daodao.storm.common.error.AppException;
import cloud.daodao.storm.security.util.CaptchaUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.time.Duration;
import java.util.Base64;
import java.util.UUID;

@Slf4j
@Service
public class CaptchaService {

    @Resource
    private AppConfig appConfig;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    public CaptchaData captchaCode() {
        // String captchaExec = appConfig.getCaptchaExec();
        // String[] results = CommandUtil.exec(new String[]{captchaExec, "-l", "4", "-d", "true"});
        // String code = results[0];
        // String image = results[1];
        String code = CaptchaUtil.getRandomCode();
        // 将验证码与验证码对应的id存入到redis中，用来验证
        String id = UUID.randomUUID().toString();
        String key = CacheConstant.CAPTCHA + id;
        stringRedisTemplate.opsForValue().set(key, code, Duration.ofMinutes(3L));
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try {
            ImageIO.write(CaptchaUtil.genCaptcha(code), "jpg", outputStream);
        } catch (IOException e) {
            log.error(e.getMessage());
            throw new AppException(SecurityError.GENERATE_CAPTCHA_ERROR, e);
        }
        String image = "data:image/jpeg;base64," + new String(Base64.getEncoder().encode(outputStream.toByteArray())).replaceAll("[\\s*\t\n\r]", "");
        CaptchaData data = new CaptchaData();
        data.setCaptchaId(id);
        data.setCaptchaImage(image);
        return data;
    }

    public void captchaCheck(CaptchaParam param) {

        String id = param.getCaptchaId();
        String code = param.getCaptchaCode();
        /*
         * 开发和测试环境为了方便自动化测试，动态配置了验证码万能密钥方案
         */
        if (appConfig.getCaptchaMasterKeyEnable() && appConfig.getCaptchaMasterKeyValue().equals(code)) {
            return;
        }
        if (id.isEmpty() || code.isEmpty()) {
            throw new AppException(SecurityError.CAPTCHA_NOT_NULL, param.toJson());
        }
        String key = CacheConstant.CAPTCHA + id;
        String value = stringRedisTemplate.opsForValue().get(key);
        if (null == value) {
            throw new AppException(SecurityError.CAPTCHA_EXPIRE, param.toJson());
        }
        if (!value.equalsIgnoreCase(code)) {
            stringRedisTemplate.delete(key);
            throw new AppException(SecurityError.CAPTCHA_ERROR, param.toJson());
        }
        stringRedisTemplate.delete(key);

    }

}
